package com.rws;

import com.rws.exception.SubjectException;
import com.rws.message.LockMessage;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 单例对象
 *  1.创建localLock锁，用来实现全局锁
 *  2.创建observers，保存所有注册的Observer对象
 * @Author 谢卓才
 * @Date 2022/10/23 17:20
 */
public class SubjectLocalContext {

    private SubjectLocalContext(){
    }

    /**
     * 全局锁
     */
    private final static ReadWriteLock localLock = new ReentrantReadWriteLock();

    /**
     * 注册Observer对象的集合
     */
    private final static List<Observer> observers = new CopyOnWriteArrayList<>();

    /**
     * 注册Observer对象
     * @param observer
     */
    public static void createObserver(Observer observer){
        if(observers.contains(observer)){
            throw new SubjectException("Observer cannot be added repeatedly");
        }
        if(observer.getName() == null || observer.getName().isEmpty()){
            throw new SubjectException("Observer name is null");
        }
        observers.add(observer);
    }

    public static List<Observer> getObservers(){
        return observers;
    }

    /**
     * ------------------------------------------------------------------------------------
     * 下方是推送消息的实现方法
     */

    public static Object putWriteMessage(LockMessage message, String targetName){
        return putWriteMessage(message,targetName,null);
    }

    public static Object putWriteMessage(LockMessage message, String targetName, ReadWriteLock lock){
        if(lock == null){
            return new ReadWriteSubject(localLock.writeLock(), observers, null).putLockMessage(message,targetName);
        } else {
            return new ReadWriteSubject(lock.writeLock(),observers, null).putLockMessage(message,targetName);
        }
    }

    public static Object putReadMessage(LockMessage message, String targetName){
        return putReadMessage(message,targetName,null);
    }

    public static Object putReadMessage(LockMessage message, String targetName, ReadWriteLock lock){
        if(lock == null){
            return new ReadWriteSubject(localLock.readLock(),observers, null).putLockMessage(message,targetName);
        } else {
            return new ReadWriteSubject(lock.readLock(),observers, null).putLockMessage(message,targetName);
        }
    }

    public Object putMessage(LockMessage message, String targetName){
        return putMessage(message,targetName,null);
    }

    public Object putMessage(LockMessage message, String targetName, ReadWriteLock lock){
        if(lock == null){
            return new ReadWriteSubject(null,observers, null).putMessage(message,targetName);
        } else {
            return new ReadWriteSubject(null,observers, null).putMessage(message,targetName);
        }
    }
}
